package com.billing.service;

import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.billing.aop.Auditable;
import com.billing.persistance.dao.IGenericDAO;
import com.billing.persistance.entities.BillOwner;
import com.billing.persistance.entities.BillingEntry;
import com.billing.persistance.entities.BillingEntryConcept;

@Service
public class BillingServiceImpl implements IBillingService {

	@Autowired
	@Qualifier(value = "billingEntryDAO")
	private IGenericDAO<BillingEntry, Long> billingDAO;

	@Autowired
	@Qualifier(value = "billingOwnerDAO")
	private IGenericDAO<BillOwner, Long> billOwnerDAO;

	@Autowired
	@Qualifier(value = "billingEntryConceptDAO")
	private IGenericDAO<BillingEntryConcept, Long> billingConceptDAO;

	@Auditable
	@Transactional
	public long addNewBillingEntry(@Valid BillingEntry billingEntry) {

		// FIXME Check that all the fields are not null (add validation!)
		
		// Check if the payee already exists
		Long payeeId = billingEntry.getPayee().getId();

		BillOwner payee = billOwnerDAO.read(payeeId);
		if (payee == null){
			// If it does not exist, create it
			billOwnerDAO.create(payee);
		}
		
		// Check if the payer already exits
		Long payerId = billingEntry.getPayer().getId();
		BillOwner payer = billOwnerDAO.read(payerId);
		if (payer == null){
			// If it does not exist, create it
			billOwnerDAO.create(payer);
		}
		
		// Check if the accounting concept exists
		Long conceptID = billingEntry.getBillingEntryConcept().getId();
		BillingEntryConcept concept = billingConceptDAO.read(conceptID);
		
		if (concept == null){
			// If it does not exist, create it
			billingConceptDAO.create(concept);
		}

		 return billingDAO.create(billingEntry);
	}

	@Auditable
	@Transactional
	public void removeBillingEntry(BillingEntry billingEntry) {
		billingDAO.delete(billingEntry);
	}

	@Auditable
	@Transactional
	public void updateBillingEntry(BillingEntry billingEntry) {
		billingDAO.update(billingEntry);
	}

	@Transactional(readOnly = true)
	public BillingEntry getBillingEntry(long id) {
		return billingDAO.read(id);
	}

	@Transactional(readOnly = true)
	public List<BillingEntry> getBillingEntries() {
		
		return billingDAO.getList("") ;
	}

}
